package com.infore.dataReceiving.util;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import com.infore.dataReceiving.dto.OverStateDto;
import com.infore.dataReceiving.dto.WaterInstructionsDataDto;
import com.infore.dataReceiving.enums.QualityProjectEnum;
import com.infore.dataReceiving.enums.WaterQualityTargetLevel;

/**
 * 水质等级计算工具
 * @author cys
 *
 */
public class WaterQualityUtil {
    
    public static final int invalidLevel = 999999;
    
    /** 水质等级 */
    private static final Map<String, Integer> LEVEL = new HashMap<String, Integer>() {
        private static final long serialVersionUID = 1L;

        {
            put("default", 0);
            put("one", 1);
            put("two", 2);
            put("three", 3);
            put("four", 4);
            put("five", 5);
            put("vfive", 6);
        }
    };
    
    /** 因子等级标准 */
    private static final Map<String, List<Double>> projectWaterQuality = new HashMap<String, List<Double>>() {
        private static final long serialVersionUID = 12L;

        {
            put("w01009", Arrays.asList(7.5, 6.0 , 5.0, 3.0, 2.0));//溶解氧 //大于
            put("w21003", Arrays.asList(0.15, 0.5, 1.0, 1.5, 2.0)); //氨氮
            put("w21011", Arrays.asList(0.02, 0.1 , 0.2, 0.3, 0.4)); //总磷
            put("w21001", Arrays.asList(0.2, 0.5 , 1.0, 1.5, 2.0));//总氮
            put("w01019", Arrays.asList(2.0, 4.0 , 6.0, 10.0, 15.0)); //高锰酸盐指数
        }
    };
    
    public static String waterQualityEvaluation(Integer level) {
        if(level==1||level==2) {
            return "优";
        }else if(level==3) {
            return "良好";
        }else if(level==4) {
            return "轻度污染";
        }else if(level==5) {
            return "中度污染";
        }else if(level==6) {
            return "重度污染";
        }else {
            return "-";
        }
    }

    public static void setWaterQuality(List<WaterInstructionsDataDto> finalList) {
        // TODO Auto-generated method stub
        String value = null;
        Integer level = null;
        Iterator<WaterInstructionsDataDto> it = finalList.iterator();
        List<WaterInstructionsDataDto> wryList = new ArrayList<WaterInstructionsDataDto>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date time = null, now = new Date();
        while (it.hasNext()) {
            WaterInstructionsDataDto data = it.next();
            int maxLevel = 0;
            StringBuilder result = new StringBuilder();
            for (String code : projectWaterQuality.keySet()) {
                try {
                    Field field = data.getClass().getDeclaredField(code);
                 // 对象的属性的访问权限设置为可访问
                    field.setAccessible(true);
                    value = field.get(data) == null ? null : field.get(data).toString();
                    level = getWaterLevel(code, value);
                    if(level != null && level > 3) {
                        result.append(QualityProjectEnum.getName(code)).append(",");
                    }
                    if(level != null && level > maxLevel) {
                        maxLevel = level;
                    }
                } catch (NoSuchFieldException e) {
                    continue;
                } catch (SecurityException e) {
                    continue;
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            if(maxLevel == 0)
                maxLevel = invalidLevel;
            data.setWaterQuality(maxLevel+"");
            if(result.length() > 0) {
                data.setPrimaryPollutant(result.substring(0,result.length()-1));
            };
            data.setEvaluation(waterQualityEvaluation(maxLevel));
            int mb = 0;
            WaterQualityTargetLevel tar = WaterQualityTargetLevel.getDesc(data.getTargerWaterQuality());
            if(tar != null) {
                mb = Integer.valueOf(tar.getStatusCode());
            }
           
            String t = data.getDataTime();
            if(StringUtils.isNotBlank(t)) {
                try {
                    time = sdf.parse(t);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            data.setStationState("1"); //默认正常
           // if(time != null) {
            //    if (((now.getTime() - time.getTime()) / 1000) < 3600 * 8) {
             //       data.setStationState("1");//正常 
                    if(maxLevel>mb) {
                        data.setStationState("2"); //超标
                    }
              //  }
         //   }
            
            if("002".equals(data.getStationType())) {
            	wryList.add(data);
            }
        }
        if(wryList.size()>0) {
        	PolluteStandardUtil.setPolluteStandard(wryList);
        }
       
    }

    public static Integer getWaterLevel(String code, String value) {
        if(code == null || value == null)
            return null;
        List<Double> levelList = projectWaterQuality.get(code);
        if (levelList == null) {
        	return null;
		}
        double val = Double.valueOf(value);
        if (code.equals("w01009")){
            for (int i = 0; i < levelList.size(); i++) {
                if(val >= levelList.get(i)) {
                    return i+1;
                }
            }
        }else {
            for (int i = 0; i < levelList.size(); i++) {
                if(val <= levelList.get(i)) {
                    return i+1;
                }
            } 
        }
        return LEVEL.get("vfive");
        
    }
    
    public static String getStandord(String code, String value, int mb) {
        if(code == null || value == null || mb > 5)
            return "";
        List<Double> levelList = projectWaterQuality.get(code);
        if (levelList == null) {
            return "";
        }
        double val = Double.valueOf(value);
        DecimalFormat df = new DecimalFormat("#.##");
        double s =  levelList.get(mb-1);
        if (code.equals("w01009")){
            double u = levelList.get(4);
            String b = df.format((s - val)/s);
            return "--(参考标准下限值："+s+")，超标下限倍数："+b;
           
        }else {
            double u = levelList.get(0);
            String b = df.format((val - u)/u);
            return "(参考标准上限值："+s+"，下限值："+u+")，超标倍数："+b;
        }
       
        
    }
    
    /**
     * unusual超标数据-----normal正常数据
     * 判断是不是超标,输入当前水质等级计算和目标水质等级
     * @return
     */
    public static String OverData(Integer level,Integer targetLevel) {
		if (level == null || targetLevel == null) {
			return "normal";
		}
    	if (level > targetLevel) {
			return "unusual";
		}else {
			return "normal";
		}
	}
    
    public static List<OverStateDto> wrapOverStateDtoList(List<WaterInstructionsDataDto> finalList) {
        // TODO Auto-generated method stub
        String value = null;
        Integer level = null;
        List<OverStateDto> resultList = new ArrayList<>();
        Iterator<WaterInstructionsDataDto> it = finalList.iterator();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date time = null, now = new Date();
        while (it.hasNext()) {
            WaterInstructionsDataDto data = it.next();
            int maxLevel = 0;
            int mb = 3;
            WaterQualityTargetLevel tar = WaterQualityTargetLevel.getDesc(data.getTargerWaterQuality());
            if(tar != null) {
                mb = Integer.valueOf(tar.getStatusCode());
            }
            OverStateDto overData = null;
            for (String code : projectWaterQuality.keySet()) {
                try {
                    Field field = data.getClass().getDeclaredField(code);
                 // 对象的属性的访问权限设置为可访问
                    field.setAccessible(true);
                    value = field.get(data) == null ? null : field.get(data).toString();
                    level = getWaterLevel(code, value);
                    if(level != null && level > mb) {
                        System.out.println(data.getStationName());
                        //超标
                        overData = new OverStateDto();
                        overData.setCode(code);
                        overData.setfName(QualityProjectEnum.getName(code));
                        overData.setMn(data.getMn());
                        overData.setStationName(data.getStationName());
                        overData.setTime(data.getDataTime());
                        overData.setValue(value);
                        String c = getStandord(code, value, mb);
                        String content = data.getDataTime()+","+data.getStationName()+",超标因子"+overData.getfName()
                        +",当前值为："+overData.getValue()+c;
                        overData.setContent(content);
                    }
                } catch (NoSuchFieldException e) {
                    continue;
                } catch (SecurityException e) {
                    continue;
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
           
            String t = data.getDataTime();
            if(StringUtils.isNotBlank(t)) {
                try {
                    time = sdf.parse(t);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(time != null  && overData != null) {
               // if (((now.getTime() - time.getTime()) / 1000) < 3600 * 8) {
                    resultList.add(overData);
               // }
            }
        }
       return resultList;
       
    }
}
